<?php

namespace aliservice\think\apisign;

use aliservice\think\apisign\exceptions\SignErrorException;
use aliservice\think\apisign\exceptions\SignNonExistentException;

class Application
{
    /**
     * 生成签名
     * @param $data
     * @param $timestamp
     * @param string $randStr
     * @return array
     */
    public function make($data, $timestamp, string $randStr): array
    {
        unset($data['sign']);
        $data = array_filter($data);
        ksort($data);
        $string = '';
        foreach ($data as $key => $datum) {
            if (is_array($datum) || is_object($datum)) {
                continue;
            }
            $string .= $key . '=' . $datum . '&';
        }
        $salt_str    = config('api_sign.salt');
        $salts       = explode(',', $salt_str);
        $return_data = [];
        foreach ($salts as $salt) {
            if (!$salt) continue;
            $return_data[] = strtoupper(md5($string . $salt . $timestamp . $randStr));
        }
        return $return_data;
    }

    /**
     * 校验签名
     * @param $data
     * @param $timestamp
     * @param $randStr
     * @param $sign
     * @return string
     * @throws SignErrorException
     * @throws SignNonExistentException
     */
    public function check($data, $timestamp, $randStr, $sign): string
    {
        if (!$timestamp || !$randStr || !$sign) {
            throw new SignNonExistentException();
        }
        $timestamp_expire_in = config('api_sign.timestamp_expire_in');
        if ($timestamp > time() + $timestamp_expire_in) {
            throw new SignNonExistentException();
        }
        if ($timestamp < time() - $timestamp_expire_in) {
            throw new SignNonExistentException();
        }
        $build_sign_list = $this->make($data, $timestamp, $randStr);
        if (!in_array($sign, $build_sign_list)) {
            throw new SignErrorException();
        }
        return $sign;
    }
}